using System;
using System.Windows.Forms;
using System.Drawing;

/// <summary>
/// Layouts subcontrols horizontaly or verticaly.
/// Controls are stretched according to Anchor and Dock styles.
/// </summary>
namespace EForms
{
	public class EPanelFlow : UserControl
	{
		/// <summary>
		/// Panel layout.
		/// </summary>
		public enum Orientations { Horizontal=1, Vertical }
	
		/// <summary>
		/// Creates instance.
		/// </summary>
		public EPanelFlow(Orientations orientation, 
			params Control[] controls) : this(orientation, 0, controls)
		{
		}
	
		/// <summary>
		/// Creates instance.
		/// </summary>
		public EPanelFlow(Orientations orientation, 
			int space, 
			params Control[] controls) : this(null, orientation, space, controls)
		{
		}
	
		/// <summary>
		/// Creates instance.
		/// </summary>
		public EPanelFlow(string name, 
			Orientations orientation, 
			int space, 
			params Control[] controls)
		{
			this.Orientation = orientation;
			this.Space = space;
			this.Layout += new LayoutEventHandler(this.Panel_Layout);
			this.Name = name;
			this.Controls.AddRange(controls);
		}
	
		/// <summary>
		/// Current layout.
		/// </summary>
		public Orientations Orientation;
	
		/// <summary>
		/// Space between controls.
		/// </summary>
		public int Space;
	
		protected void Panel_Layout(object sender, LayoutEventArgs e)
		{
			int count = 0;
			foreach (Control control in this.Controls) if (control.Visible) count++;
			if (count <= 0) return;

			for (int i=0; i<this.Controls.Count; i++)
			{
				//DockStyle.Fill -> AnchorStyle.Top|Bottom|Left|Right
				if (this.Controls[i].Dock == DockStyle.Fill)
				{
					this.Controls[i].Dock = DockStyle.None;
					this.Controls[i].Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
				}
				if (!this.Controls[i].Visible) continue;
			
				//shortcuts
				bool top = (this.Controls[i].Anchor & AnchorStyles.Top) != 0;
				bool bottom = (this.Controls[i].Anchor & AnchorStyles.Bottom) != 0;
				bool left = (this.Controls[i].Anchor & AnchorStyles.Left) != 0;
				bool right = (this.Controls[i].Anchor & AnchorStyles.Right) != 0;
				bool horizontal = this.Orientation == Orientations.Horizontal;

				//stretch by Anchor
				if (top && bottom) this.Controls[i].Height = horizontal ? this.ClientSize.Height : this.ClientSize.Height/count-(count-1)*this.Space;
				if (left && right) this.Controls[i].Width = horizontal ? this.ClientSize.Width/count-(count-1)*this.Space : this.ClientSize.Width;
			
				//location
				this.Controls[i].Location = horizontal ?
					new Point(this.ClientSize.Width*i/count+i*this.Space+(left?0:(this.ClientSize.Width/count-this.Controls[i].Width)/(right?1:2)), top?0:(this.ClientSize.Height-this.Controls[i].Height)/(bottom?1:2)) :
					new Point(left?0:(this.ClientSize.Width-this.Controls[i].Width)/(right?1:2), this.ClientSize.Height*i/count+i*this.Space+(top?0:(this.ClientSize.Height/count-this.Controls[i].Height)/(bottom?1:2)));
			}
		}
	}//FlowPanel{}
}